package org.sction.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 作者 : sorc
 * @version 创建时间：2012-3-20 上午8:38:16
 * 
 *          类说明
 */
public class FileUtils {
	public static String FILE_UPLOAD_DIR = "";

	public static String getInnerFilePath(String destdir, String filename)
			throws FileNotFoundException, IOException {
		if (destdir == null) {
			destdir = FileUtils.URLToString(FileUtils.class.getResource("/"));
		}
		File file = new File(destdir + "/" + filename);
		if (file == null || !file.exists()) {
			return FileUtils.unzipFile(filename, destdir, true);
		} else {
			return file.getPath();
		}
	}

	/**
	 * 复制流
	 * 
	 * @param input
	 * @param out
	 * @param bufferSize
	 * @throws IOException
	 */
	public static void copyStream(InputStream input, OutputStream out,
			int bufferSize) throws IOException {
		byte[] buff = new byte[bufferSize];
		int len = 0;
		while ((len = input.read(buff)) != -1) {
			out.write(buff, 0, len);
		}
		out.close();
		input.close();
	}

	/**
	 * 按路径复制文件
	 * 
	 * @param input
	 * @param out
	 * @param bufferSize
	 * @throws IOException
	 */
	public static void copy(String input, String out, int bufferSize)
			throws IOException {
		File of = new File(out);
		if (!of.getParentFile().exists()) {
			of.getParentFile().mkdirs();
		}
		copyStream(new FileInputStream(input), new FileOutputStream(out),
				bufferSize);
	}

	/**
	 * 列所有文件
	 * 
	 * @param src
	 * @return
	 */
	public static List<File> listFiles(File src) {
		List<File> list = new ArrayList<File>();
		if (src.exists()) {
			if (src.isFile()) {
				list.add(src);
			} else {
				File[] files = src.listFiles();
				for (File file : files) {
					if (file.isFile()) {
						list.add(file);
					} else {
						list.addAll(listFiles(file));
					}
				}
			}
		}
		return list;
	}

	/**
	 * 修复路径
	 * 
	 * @param dir
	 * @return
	 */
	public static String fixedDir(String dir) {
		if (dir == null || dir.trim().equals("")) {
			return null;
		}
		if (dir == null || dir.trim().equals("")) {
			File file = new File("");
			dir = file.getAbsoluteFile().getParent();
			dir = dir.replace("\\", File.separator);
			dir = dir.replace("/", File.separator);
			while (dir.endsWith(File.separator)) {
				dir = dir.substring(0, dir.length() - 1);
			}
		} else {
			dir = dir.trim();
			dir = dir.replace("\\", File.separator);
			dir = dir.replace("/", File.separator);
			while (dir.endsWith(File.separator)) {
				dir = dir.substring(0, dir.length() - 1);
			}
		}
		dir = dir.replace(File.separator + File.separator, File.separator);
		// File dirF = new File(dir);
		// if (!dirF.exists() || !dirF.isDirectory()) {
		// dirF.mkdirs();
		// }
		return dir;
	}

	public static boolean copyDir(String src, String destDir, int bufferSize) {
		src = fixedDir(src);
		destDir = fixedDir(destDir);
		File srcfile = new File(src);
		List<File> list = listFiles(srcfile);
		int ix = src.length();
		if (srcfile.isFile()) {
			ix = srcfile.getParent().length();
		}
		boolean copyflag = true;
		for (File file : list) {
			try {
				copy(file.getPath(), destDir + file.getPath().substring(ix),
						bufferSize);
			} catch (IOException e) {
				copyflag = false;
			}
		}
		return copyflag;
	}

	/**
	 * 复制URL流
	 * 
	 * @param url
	 * @param out
	 * @param bufferSize
	 * @throws IOException
	 */
	public static void copyStream(URL url, OutputStream out, int bufferSize)
			throws IOException {
		InputStream input = url.openStream();
		byte[] buff = new byte[bufferSize];
		int len = 0;
		while ((len = input.read(buff)) != -1) {
			out.write(buff, 0, len);
		}
		out.close();
		input.close();
	}

	/**
	 * 读取流到字符串
	 * 
	 * @param input
	 * @return
	 * @throws IOException
	 */
	public static String read(InputStream input) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(input));
		String line = "";
		String out = "";
		while ((line = reader.readLine()) != null) {
			out += line + "\n";
		}
		reader.close();
		return out;
	}

	/**
	 * 读取文件到字符串
	 * 
	 * @param filepath
	 * @return
	 * @throws IOException
	 */
	public static String read(String filepath) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				new FileInputStream(filepath)));
		String line = "";
		String out = "";
		while ((line = reader.readLine()) != null) {
			out += line + "\n";
		}
		reader.close();
		return out;
	}

	/**
	 * 读取URL到字符串
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public static String read(URL url) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				url.openStream()));
		String line = "";
		String out = "";
		while ((line = reader.readLine()) != null) {
			out += line + "\n";
		}
		reader.close();
		return out;
	}

	/**
	 * 将字符串写入文件
	 * 
	 * @param path
	 * @param str
	 * @throws IOException
	 */
	public static void write(String path, String str) throws IOException {
		File dir = new File(path).getParentFile();
		if (!dir.exists() || !dir.isDirectory()) {
			dir.mkdirs();
		}
		FileWriter fw = new FileWriter(path, false);
		BufferedWriter bw = new BufferedWriter(fw);
		bw.write(str);
		bw.close();
	}

	/**
	 * 解压缩文件
	 * 
	 * @param url
	 * @param isCover
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static String unzipFile(String url, boolean isCover)
			throws FileNotFoundException, IOException {

		return FileUtils.unzipFile(url, "", isCover);
	}

	/**
	 * 解压缩文件
	 * 
	 * @param path
	 * @param tempPath
	 * @param isCover
	 * @return
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public static String unzipFile(String path, String tempPath, boolean isCover)
			throws FileNotFoundException, IOException {
		URL url = FileUtils.class.getResource("/" + path);
		String destPath = tempPath;
		File destPathFile = new File(destPath);
		if (destPath == null || destPath.equals("")) {
			destPath = FileUtils.class.getResource("/").toString();
			destPathFile = new File(destPath);
			destPath = destPathFile.getParent();
			destPath += File.separator + "temp" + File.separator;
		}
		destPath += path;
		destPathFile = new File(destPath);
		File dir = destPathFile.getParentFile();

		if (!dir.exists() || !dir.isDirectory()) {
			dir.mkdirs();
		}
		OutputStream out = new FileOutputStream(destPathFile);
		FileUtils.copyStream(url, out, 1024);
		return destPath;
	}

	/**
	 * 删除文件 删除子目录子文件
	 * 
	 * @param f
	 * @return
	 */
	public boolean deleteFile(File f) {
		if (f.exists()) {
			if (f.isFile()) {
				return f.delete();
			} else if (f.isDirectory()) {
				File[] files = f.listFiles();
				for (int i = 0; i < files.length; i++) {
					if (!deleteFile(files[i]))
						return false;
				}
				return f.delete();
			} else
				return false;
		} else
			return false;
	}

	/**
	 * 删除指定目录下的所有文件
	 * 
	 * @param folderPath
	 *            目录路径
	 * @return true:删除成功 false:删除失败
	 */
	public static boolean delAllFile(String folderPath) {
		boolean flag = false;
		File file = new File(folderPath);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (folderPath.endsWith(File.separator)) {
				temp = new File(folderPath + tempList[i]);
			} else {
				temp = new File(folderPath + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(folderPath + "/" + tempList[i]);// 先删除文件夹里面的文件
				delFolder(folderPath + "/" + tempList[i]);// 再删除空文件夹
				flag = true;
			}
		}
		return flag;
	}

	/**
	 * 删除指定文件
	 * 
	 * @param filePath
	 *            指定文件的路径
	 * @return true:删除成功 false:删除失败
	 */
	public static boolean delFile(String filePath) {
		boolean flag = false;
		File file = new File(filePath);
		if (!file.exists()) {
			return flag;
		}
		flag = (new File(filePath)).delete();
		return flag;
	}

	/**
	 * 删除指定文件夹(包括文件夹下的所有文件)
	 * 
	 * @param folderPath
	 *            指定文件夹路径
	 * @return true:删除成功 false:删除失败
	 */
	public static boolean delFolder(String folderPath) {
		try {
			delAllFile(folderPath); // 删除完里面所有内容
			String filePath = folderPath;
			filePath = filePath.toString();
			java.io.File myFilePath = new java.io.File(filePath);
			myFilePath.delete(); // 删除空文件夹
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static String URLToString(URL url) {
		String path = url.toString();
		if (Math.max(path.indexOf("file:\\"), path.indexOf("file:/")) == 0) {
			path = path.substring(6);
		} else if (Math.max(path.indexOf("\\"), path.indexOf("/")) == 0) {
			path = path.substring(1);
		}
		return path;
	}

	public static String getRelativePath(String file, String rootdir) {
		int index = file.replaceAll("\\\\", "/").indexOf(
				rootdir.replaceAll("\\\\", "/"));
		if (index == 0) {
			return file.substring(index);
		}
		return null;
	}

	/**
	 * 获得文件名带后缀
	 * 
	 * @param fileAllPath
	 * @return
	 */
	public static String getFileName(String fileAllPath) {
		int index = Math.max(fileAllPath.lastIndexOf("\\"),
				fileAllPath.lastIndexOf("/"));
		return fileAllPath.substring(index == -1 ? 0 : index);
	}

	/**
	 * 不带后缀
	 * 
	 * @param fileAllPath
	 * @return
	 */
	public static String getFileSimpleName(String fileAllPath) {
		int index = Math.max(fileAllPath.lastIndexOf("\\"),
				fileAllPath.lastIndexOf("/"));
		int dotx = fileAllPath.lastIndexOf(".");
		return fileAllPath.substring(index == -1 ? 0 : index,
				dotx == -1 ? fileAllPath.length() : dotx);
	}

	/**
	 * 带点的后缀
	 * 
	 * @param filePath
	 * @return
	 */
	public static String getFileSuffixName(String filePath) {
		int dotx = filePath.lastIndexOf(".");
		return dotx == -1 ? "" : filePath.substring(dotx);
	}

	/**
	 * 不带点的后缀
	 * 
	 * @param filePath
	 * @return
	 */
	public static String getFileSuffixNoDot(String filePath) {
		String suffix = getFileSuffixName(filePath);
		return suffix.startsWith(".") ? suffix.substring(1) : suffix;
	}

	public static String getFileSize(double size) {
		double fsizet = 0;
		fsizet = size;
		DecimalFormat df = new DecimalFormat("#.00");
		String[] suffixs = { "B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB",
				"YB" };
		for (int i = 0; i < suffixs.length; i++) {
			double p = Math.pow(2, i * 10);
			double pmax = Math.pow(2, (i + 1) * 10);
			if (fsizet < pmax) {
				return df.format(fsizet / p) + " " + suffixs[i];
			}
		}
		return df.format(fsizet / Math.pow(2, (suffixs.length - 1) * 10)) + " "
				+ suffixs[suffixs.length - 1];
	}

	public static String getFileSize(long size) {
		if (size == Long.MAX_VALUE) {
			System.out.println("警告！数据有可能已超出Long最大长度");
		}
		return FileUtils.getFileSize((double) size);
	}

	/**
	 * 获得文件大小的 显示方式 kb mb gb
	 * 
	 * @param path
	 * @return
	 */
	public static String getFileSizeString(String path) {
		File file = new File(path);
		return getFileSize(file.length());

	}

	/**
	 * 取跟路径
	 * 
	 * @param path
	 * @return
	 */
	public static String getFileRoot(String path) {
		File dir = new File(path);
		if (path == null || path.trim().equals("")) {
			dir = new File(path).getAbsoluteFile();
		}
		String root = "/";
		File roots[] = File.listRoots();
		for (int i = 0; i < roots.length; i++) {
			if (dir.getPath().toLowerCase()
					.startsWith(roots[i].getPath().toLowerCase())) {
				root = roots[i].getPath();
				break;
			}
		}
		return root;
	}

	public static void main(String[] args) {
		System.out.println(FileUtils.getFileName("ssdfdsa.doc"));
		System.out.println(FileUtils.getFileSimpleName("ssdfdsa.doc"));
		System.out.println(FileUtils.getFileSuffixName("ssdfdsa.doc"));
		System.out.println(getFileRoot(""));
	}
}
